--[[
Name: unitDoodles.config
Author: Sonora (The Dragonflight, US Kirin Tor)
Website & SVN: http://code.google.com/p/browniehelper/source/browse/#svn/trunk/unitDoodles.config
License: GNU General Public License v3
]]

local AceConfig = LibStub("AceConfig-3.0")
local AceConfigDialog = LibStub("AceConfigDialog-3.0")

--Some Lua utility functions
local function hasValue(t, value)
    for _, v in ipairs(t) do
        if v == value then return true end
    end
    for k, v in pairs(t) do
        if v == value then return true end
    end
end

local function deepcopy(object)
    local lookup_table = {}
    local function _copy(object)
        if type(object) ~= "table" then
            return object
        elseif lookup_table[object] then
            return lookup_table[object]
        end
        local new_table = {}
        lookup_table[object] = new_table
        for index, value in pairs(object) do
            new_table[_copy(index)] = _copy(value)
        end
        return setmetatable(new_table, _copy(getmetatable(object)))
    end
    return _copy(object)
end

--Ace3 addon application object.  We're like so totally Ace3 embedding.
unitDoodlesConfig = LibStub("AceAddon-3.0"):NewAddon("unitDoodlesConfig", "AceConsole-3.0", "AceComm-3.0", "AceSerializer-3.0")
local defaultConfig = deepcopy(unitDoodles.config)

--Core UI setup and DB handling
function unitDoodlesConfig:OnInitialize()
    
    --Setup a default profile table for the database (built-in unitDoodles .config)
    local defaultProfileDb = {
        profile = {
            config = defaultConfig
        }
    }
    
    --Setup data base communication    
    self.db = LibStub("AceDB-3.0"):New("unitDoodlesDb", defaultProfileDb)
    self.db.RegisterCallback(self, "OnProfileChanged", "OnProfileChanged")
    
    --Register us as recievers of our AceComm messages
    self:RegisterComm('unitDoodles.sendDoodles', 'sendDoodlesReciever')
    
    --If SharedMedia is loaded, share our media
    if IsAddOnLoaded("SharedMedia") then
        local lib = LibStub("LibSharedMedia-3.0")
        lib:Register(lib.MediaType.STATUSBAR, "unitDoodles.Bar", [=[Interface\Addons\unitDoodles\media\barTex]=])
        lib:Register(lib.MediaType.STATUSBAR, "unitDoodles.Dot", [=[Interface\Addons\unitDoodles\media\bubbleTex]=])
    end

    --This call in turn handles changes to unitDoodls.config and config GUI construction
    self:OnProfileChanged(nil, self.db, self.db:GetCurrentProfile())
    
    --Setup the user interface
    self:initializeUI()
    
end

function unitDoodlesConfig:OnProfileChanged(eventName, db, newProfile)
    
    self.config = db.profile.config
    self:updateConfig()
    
end

function unitDoodlesConfig:panelLoader(panelName, createCall)
    return function()
        local panel = createCall(self, self:panelLoader(panelName, createCall))
        AceConfig:RegisterOptionsTable(panelName, panel)
        if InterfaceOptionsFrame:IsShown() then
            AceConfigDialog:SelectGroup(panelName)
        end
        return panel
    end
end

function unitDoodlesConfig:initializeUI()
    
    --[[
    Options panels injected into default UI
    ]]--    
    local basePanel = self:panelLoader("unitDoodles", self.createBasePanel)() --See if select group true here does anything weird
    local localBaseFrame = AceConfigDialog:AddToBlizOptions("unitDoodles", "unitDoodles")
    
    --AceConfig:RegisterOptionsTable("unitDoodles.doodleSets", self:createDoodleSetsPanel(reloadPanel("unitDoodles.doodleSets")))
    self:panelLoader("unitDoodles.doodleSets", self.createDoodleSetsPanel)()
    AceConfigDialog:AddToBlizOptions("unitDoodles.doodleSets", "Doodles", "unitDoodles")
    
    --AceConfig:RegisterOptionsTable("unitDoodles.unitFrames", self:createUnitFramesPanel(reloadPanel("unitDoodles.unitFrames")))
    self:panelLoader("unitDoodles.unitFrames", self.createUnitFramesPanel)()
    AceConfigDialog:AddToBlizOptions("unitDoodles.unitFrames", "Unit frames", "unitDoodles")
    
    AceConfig:RegisterOptionsTable("unitDoodles.Profiles", LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db))
    AceConfigDialog:AddToBlizOptions("unitDoodles.Profiles", "Profiles", "unitDoodles")
    
    --TODO: debug code, remove
    --InterfaceOptionsFrame_OpenToCategory(localBaseFrame)
    
end

--Function called by unitDoodles framework before doodles are built
function unitDoodlesConfig:updateConfig()
    
    --Push local configuration to unitDoodles and initialize the setup  
    unitDoodles.config = deepcopy(self.config)
    unitDoodles.buildDoodles()
    unitDoodles.eventHandlers.UNIT_AURA()
    
    self.shouldReload = true
    
end

--Convenience functions
function unitDoodlesConfig:doodleSetIsLoaded(doodleSetName)
    local loadedSets = self:getDoodleSetNames(true)
    if hasValue(self.config.loadDoodleSets, doodleSetName) then 
        return true 
    else
        return false
    end
end

function unitDoodlesConfig:getDoodleSetNames(filterLoaded)
    --[[
    filterLoaded = nil          returns all doodle set names
    filterLoaded = true         returns all loaded doodle set names
    filterLoaded = false        returns all not loaded doodle set names
    ]]--
   
   local doodleSetNames = {}
   for name,_ in pairs(unitDoodles.config.doodleSets) do
       if filterLoaded == nil or 
         (filterLoaded == true and hasValue(self.config.loadDoodleSets,name)) or
         (filterLoaded == false and not hasValue(self.config.loadDoodleSets,name)) then
            table.insert(doodleSetNames, name)
        end
   end
   return doodleSetNames
end

function unitDoodlesConfig:getUnitNames(includeMacros)

    local uniqueNames = {}
    for addonName, frameSet in pairs(self.config.frameSets) do
        for unitName, frameName in pairs(frameSet) do
            if unitName ~= 'playerInGroupFrames' and unitName~='getFrame' then
                uniqueNames[unitName] = true
            end
        end
    end
    
    if includeMacros==true then
        for macroName, unitList in pairs(self.config.unitMacros) do
            uniqueNames[macroName] = true
        end
    end
    
    local unitNames = {}
    for k,_ in pairs(uniqueNames) do
        table.insert(unitNames, k)
    end
    
    return unitNames

end

